﻿using System.Collections.Generic;
using IQIGame.Onigao.Framework.Serialization;
using IQIGame.Onigao.GamePlay;

namespace IQIGame.Onigao.Logic
{
    public class SkillConfig : ISerializeByteBuf
    {
        public string name;
        public List<SkillPartConfig> parts = new List<SkillPartConfig>();
        public List<TriggerConfig> triggers = new List<TriggerConfig>();

        public virtual void Serialize(ByteBuf _buf)
        {
            _buf.WriteString(this.name);
            SerializeByteBufUtil.SerializeList(_buf, this.parts);
            SerializeByteBufUtil.SerializeList(_buf, this.triggers);
        }

        public virtual void DeSerialize(ByteBuf _buf)
        {
            this.name = _buf.ReadString();
            this.parts = _buf.DeSerializeList<SkillPartConfig>();
            this.triggers = _buf.DeSerializeList<TriggerConfig>();
        }
    }

    public class SkillPartConfig : ISerializeByteBuf
    {
        public int aiMoveType;

        public SkillConditionConfig condition;
        public List<SkillEffectiveConfig> effectives = new List<SkillEffectiveConfig>();
        public long guid;
        public string name;
        public long nextGUID;
        public int partType;
        public string timeline;

        public void Serialize(ByteBuf _buf)
        {
            _buf.WriteLong(this.guid);
            _buf.WriteString(this.name);
            _buf.WriteString(this.timeline);
            _buf.WriteInt(this.partType);
            _buf.WriteLong(this.nextGUID);
            _buf.WriteInt(this.aiMoveType);

            _buf.SerializeList(this.effectives);
            _buf.SerializeObject(this.condition);
        }

        public void DeSerialize(ByteBuf _buf)
        {
            this.guid = _buf.ReadLong();
            this.name = _buf.ReadString();
            this.timeline = _buf.ReadString();
            this.partType = _buf.ReadInt();
            this.nextGUID = _buf.ReadLong();
            this.aiMoveType = _buf.ReadInt();

            this.effectives = _buf.DeSerializeList<SkillEffectiveConfig>();
            this.condition = _buf.DeSerializeObject<SkillConditionConfig>();
        }
    }

    public class SkillConditionConfig : ISerializeByteBuf
    {
        public long falsePart;
        public int formulaID;
        public long guid;
        public long truePart;

        public void Serialize(ByteBuf _buf)
        {
            _buf.WriteLong(this.guid);
            _buf.WriteInt(this.formulaID);
            _buf.WriteLong(this.truePart);
            _buf.WriteLong(this.falsePart);
        }

        public void DeSerialize(ByteBuf _buf)
        {
            this.guid = _buf.ReadLong();
            this.formulaID = _buf.ReadInt();
            this.truePart = _buf.ReadLong();
            this.falsePart = _buf.ReadLong();
        }
    }

    public class TriggerConfig : ISerializeByteBuf
    {
        public SkillConditionConfig condition;
        public SkillCustomConfig customConfig;
        public int priority;
        public long triggerPart;
        public int type;

        public virtual void Serialize(ByteBuf _buf)
        {
            _buf.WriteInt(this.type);
            _buf.WriteInt(this.priority);
            _buf.WriteLong(this.triggerPart);

            SerializeByteBufUtil.SerializeObject(_buf, this.customConfig);
            SerializeByteBufUtil.SerializeObject(_buf, this.condition);
        }

        public virtual void DeSerialize(ByteBuf _buf)
        {
            this.type = _buf.ReadInt();
            this.priority = _buf.ReadInt();
            this.triggerPart = _buf.ReadLong();

            this.customConfig = SkillFactory.CreateTriggerConfig(this.type, _buf);
            SerializeByteBufUtil.DeSerializeObject(_buf, ref this.condition);
        }
    }

    public class TargetSelectConfig : ISerializeByteBuf
    {
        public SkillCustomConfig customConfig;
        public bool forceInput;
        public long guid;
        public string indicator;
        public int targetRelation;
        public int type;

        public virtual void Serialize(ByteBuf _buf)
        {
            _buf.WriteLong(this.guid);
            _buf.WriteInt(this.type);
            _buf.WriteInt(this.targetRelation);
            _buf.WriteBool(this.forceInput);
            _buf.WriteString(this.indicator);
            SerializeByteBufUtil.SerializeObject(_buf, this.customConfig);
        }

        public virtual void DeSerialize(ByteBuf _buf)
        {
            this.guid = _buf.ReadLong();
            this.type = _buf.ReadInt();
            this.targetRelation = _buf.ReadInt();
            this.forceInput = _buf.ReadBool();
            this.indicator = _buf.ReadString();
            this.customConfig = TargetSelectFactory.CreateTargetSelectConfig(this.type);
            SerializeByteBufUtil.DeSerializeObject(_buf, ref this.customConfig);
        }
    }

    public class SkillEffectiveConfig : ISerializeByteBuf
    {
        public SkillCustomConfig customConfig;
        public int index;
        public TargetSelectConfig target;
        public int type;

        public virtual void Serialize(ByteBuf _buf)
        {
            _buf.WriteInt(this.type);
            SerializeByteBufUtil.SerializeObject(_buf, this.customConfig);
            SerializeByteBufUtil.SerializeObject(_buf, this.target);
        }

        public virtual void DeSerialize(ByteBuf _buf)
        {
            this.type = _buf.ReadInt();
            this.customConfig = SkillFactory.CreateEffectiveConfig(this.type, _buf);
            SerializeByteBufUtil.DeSerializeObject(_buf, ref this.target);
        }
    }

    public class SkillCustomConfig : SerializeCustomConfig
    {
    }

    public class FormulaConfig : ISerializeByteBuf
    {
        public bool isFormula;
        public int value;

        public void Serialize(ByteBuf _buf)
        {
            _buf.WriteInt(this.value);
            _buf.WriteBool(this.isFormula);
        }

        public void DeSerialize(ByteBuf _buf)
        {
            this.value = _buf.ReadInt();
            this.isFormula = _buf.ReadBool();
        }
    }


    public enum ESkillPartType
    {
        Nor,
        Main,
        Enable,
        Disable,
    }
}